package com.situ.onlinebookstore.front.aop;


import com.situ.onlinebookstore.common.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import javax.validation.UnexpectedTypeException;
import java.util.Objects;

@RestControllerAdvice
@Slf4j   //日志打印 在当前类的方法中，直接使用log对象进行日志打印
public class GlobalExceptionHandler {

    /**
     * 方法参数校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("[全局异常处理] [参数校验不通过]{}", e.getMessage(), e);
        return Result.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    /**
     * 方法RequestParam/PathVariable形式参数校验异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleConstraintViolationException(ConstraintViolationException e) {
        log.error("[全局异常处理] [参数校验不通过]{}", e.getMessage(), e);

        return Result.error(e.getMessage());
    }

    /**
     * 方法参数校验异常[类型不配备]
     */
    @ExceptionHandler(UnexpectedTypeException.class)
    public Result handleUnexpectedTypeException(UnexpectedTypeException e) {
        log.error("[全局异常处理] [参数校验类型不匹配]{}", e.getMessage(), e);

        return Result.error("校验参数类型异常，请检查注释使用是否正确");
    }

    /**
     * 前端传递参数验证异常
     * @param ex
     * @return
     */
    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException ex) {
        log.warn("[全局异常处理] [提交参数校不符合规则]{}", ex.getMessage(), ex);

        return Result.error(ex.getAllErrors().get(0).getDefaultMessage());
    }

}
